<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuU3lzLnNldGVudihMQU5HID0gXCJlblwiKVxuYGBgIn0= -->
```r
Sys.setenv(LANG = \en\)
```
<!-- rnb-source-end -->
```r
Sys.setenv(LANG = \en\)
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVJeUJCYkd3Z2JHbGljbUZ5YVdWekxpQkpJR1J2YmlkMElIUm9hVzVySUVrZ1pXNWtaV1FnZFhBZ2RYTnBibWNnZEdobGJTQmhiR3dnWW5WMElFa2daRzl1SjNRZ2QyRnVkQ0IwYnlCbWFXNWtJRzkxZENCM2FHbGphQ0J2Ym1VZ1NTZHRJRzV2ZENCMWMybHVaeTVjYmx4dWJHbGljbUZ5ZVNoMGFXUjVkbVZ5YzJVcFhHNXNhV0p5WVhKNUtITm1LVnh1YkdsaWNtRnllU2huWjNCc2IzUXlLVnh1YkdsaWNtRnllU2h0WVhCektWeHViR2xpY21GeWVTaHRZWEJ3Y205cUtWeHViR2xpY21GeWVTaDFjMjFoY0NsY2JteHBZbkpoY25rb1NWTk1VaklwWEc1c2FXSnlZWEo1S0daaFkzUnZaWGgwY21FcFhHNXNhV0p5WVhKNUtHUndiSGx5S1Z4dWJHbGljbUZ5ZVNob1pYaGlhVzRwWEc1Z1lHQWlmUT09IC0tPlxuXG5gYGByXG4jIEFsbCBsaWJyYXJpZXMuIEkgZG9uJ3QgdGhpbmsgSSBlbmRlZCB1cCB1c2luZyB0aGVtIGFsbCBidXQgSSBkb24ndCB3YW50IHRvIGZpbmQgb3V0IHdoaWNoIG9uZSBJJ20gbm90IHVzaW5nLlxuXG5saWJyYXJ5KHRpZHl2ZXJzZSlcbmxpYnJhcnkoc2YpXG5saWJyYXJ5KGdncGxvdDIpXG5saWJyYXJ5KG1hcHMpXG5saWJyYXJ5KG1hcHByb2opXG5saWJyYXJ5KHVzbWFwKVxubGlicmFyeShJU0xSMilcbmxpYnJhcnkoZmFjdG9leHRyYSlcbmxpYnJhcnkoZHBseXIpXG5saWJyYXJ5KGhleGJpbilcbmBgYFxuXG48IS0tIHJuYi1zb3VyY2UtZW5kIC0tPlxuIn0= -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuIyBBbGwgbGlicmFyaWVzLiBJIGRvbid0IHRoaW5rIEkgZW5kZWQgdXAgdXNpbmcgdGhlbSBhbGwgYnV0IEkgZG9uJ3Qgd2FudCB0byBmaW5kIG91dCB3aGljaCBvbmUgSSdtIG5vdCB1c2luZy5cblxubGlicmFyeSh0aWR5dmVyc2UpXG5saWJyYXJ5KHNmKVxubGlicmFyeShnZ3Bsb3QyKVxubGlicmFyeShtYXBzKVxubGlicmFyeShtYXBwcm9qKVxubGlicmFyeSh1c21hcClcbmxpYnJhcnkoSVNMUjIpXG5saWJyYXJ5KGZhY3RvZXh0cmEpXG5saWJyYXJ5KGRwbHlyKVxubGlicmFyeShoZXhiaW4pXG5gYGAifQ== -->
```r
# All libraries. I don't think I ended up using them all but I don't want to find out which one I'm not using.
library(tidyverse)
library(sf)
library(ggplot2)
library(maps)
library(mapproj)
library(usmap)
library(ISLR2)
library(factoextra)
library(dplyr)
library(hexbin)
# Change working directory to whatever works best for you.
setwd("C:/Users/halan/Desktop/FPU/Spring2025/StatisticalLearning/STA3241-Project-HalanBadilla-SP25/Data")
incidents <- read.csv("mass_killing_incidents_public.csv")
offenders <- read.csv("mass_killing_offenders_public.csv")
victims <- read.csv("mass_killing_victims_public.csv")
weapons <- read.csv("mass_killing_weapons_public.csv")
Here I open the four data sets that were used. All four are connected
with an “incident_id” allowing you to see what information is
connected.
incidents
offenders
victims
weapons
DATA: Mass Killing Database 2006 - Present (AS OF MARCH 15th
2025)
This project makes use of four data sets which are all connected. All
four data sets contain a column named “incident_id”, an id which links
all of them together to see what information is connected to what.
Mass Murder for this data set is defined using the definition given
by the FBI: “…the intentional killing of four or more victims by any
means within a 24-hour period, excluding the death of unborn children
and the offender(s).)
This Database is constantly being updated (Was just updated 2 hours
ago as of March 16th, 2025 at 12:50PM) and is very trustworthy. The main
contact for these data sets is Justin Myers. Justin Myers is a veteran
journalist for “The Associated Press”, they are also working with
Northeastern University’s James Alan Fox whom is also a contact.
Features(Incident [19 Columns x 615 Rows]):
Red = Categorical | Green = Numerical
- incident_id: ID of incident
- date: Date of incident
- city: City/Town name
- state: State postal code
- num_offenders: Number of
offenders
- num_killed: Number of victims
killed
- num_injured: Numnber of victims
injured
- firstcod: First cause of death
- secondcod: Second cause of death
- if_assault_rifle: Whether a rifle was
used
- type: Type of incident (ie. Family,
Felony, Public, etc.)
- situation_type: Type of situation
(ie. Arson, Drug Trade, Family Issue, etc.)
- location_type: Type of location (ie.
Commercial/Retail/Entertainment, Government/Transit, House of worship,
etc.)
- location: Location (ie.
Bar/Club/Restaurant, College, Commercial/Retail, etc.)
- longitude
- latitude
- county: County associated with
coordinates
- geocode: FIPS geocode of
location
- narrative: Description of incident
Features(Victims [6 Columns x 3174 Rows]):
- incident_id: ID for incident, used to
link the victims data.
- victim_id: ID of the victim, for
recording purposes.
- age: Age of the victim.
- race
- sex
- vorelationship: Relationship of
victim to the offender
Features(Weapons [5 Columns x 963 Rows]):
- incident_id: ID for incident, used to
link weapon to incident.
- weapon_id: ID for weapon
identification.
- weapon_type: Type of weapon.
- gun_class: Classification of gun
(Handgun, Long gun, Unknown gun class, Non-gun)
- gun_type: Type of gun (ie. Handgun,
Pistol, Revolver, Rifle, etc.)
Features(Offenders [15 Columns x 788 Rows]):
- incident_id: ID of incident, used to
connect the 4 data sets.
- offender_id: ID used for
classification of offenders (Mostly for multi-offender incidents)
- firstname
- middlename
- lastname
- suffix
- age
- race
- sex
- suicide: Whether the offender
commited suicide or not.
- deathcause: What did the offender die
by whether it was suicide or killed by a bystander/police
- outcome: What was the legal outcome
for the incident (ie. Acquitted, Arrested/Pending trial, Charges
dropped, etc.)
- criminal_justice_process: Status of
criminal justice process (ie. Arrested/Pending trial, charges dropped,
etc.)
- sentence_type: Type of sentence
convicted (ie. Acquitted, Awaiting sentencing, Committed, Death sentence
etc.)
- sentence_details: Details about the sentence convicted.
# Replace empty cells in the situation_type column in incidents with "Unknown"
incidents$situation_type[incidents$situation_type == ""] <- "Unknown"
# Subset for transforming the geo-data
varI <- incidents %>%
select(c(incident_id, longitude, latitude, firstcod, situation_type, location, num_victims_killed, num_victims_injured)) %>%
rename(lon = longitude) %>%
rename(lat = latitude)
# Transforming geo-data to be usable with usmap
transformedData <- usmap_transform(varI)
For the sake of visualization, incident 342, the 2017 Las Vegas
shooting incident was excluded as it is too much of an outlier to
properly visualize information. To see the details, below I have
provided the incident so you can see the details.
# So anyone can see the information on that event.
incidents[incidents$incident_id == 342, ]
# Filtering the observation.
tempData <- transformedData %>%
filter(incident_id != 342)
For these future visualizations there will be 2, one which will show
case the deaths while the other showcases the amount of injured and
alive survivors. For these first two, the data contains two cause of
death, the first cause of death is what we will focus on but the second
cause of death are any other means used by the offenders. For these two
visualizations only the primary causes will be used.
In this first one we can see rather clearly that the lead cause of
deaths in mass murders is shootings. The runner up to this seems to be
either stabbing or blunt force. In this graph and what you will notice
in the other graphs as well is that in general the mid west is the much
safer area relatively. The east coast specifically is strewn with mass
murders of multiple different degrees.

This visualization is similar to the last except it show cases the
amount of injured victims. This means any victims that were part of the
mass murder attempt and survived with injuries. Similar to the last, a
large portion of these correlate with the deaths, plenty of incidents
occuring in the east, west and central US yet the mountaineous/midwest
is much more barren in comparison. This could be a portrayal of simply
the population to incidents but as I do not have population data it is
hard to confirm that.

Next is the locations in which these incidents took place.
Predominantly it seems like the majority of mass murders occurred in
residences while the next closest being in universities or schools. Next
it also seems like bars/clubs/restaurants are next making me believe
that maybe there is a disproportionate amount of victims that may be in
either in there 20s to 30s, around the age you are still in school
and/or going out with friends (clubbing, eating, drinking, etc.)

With what you can see in this visualization of the surviving victims,
residences still dominate with sheer amount, however, this also
showcases that a lot more people are surviving mass murder attempts in
general and not just in residences. One may conclude that your chances
of surviving may go up significantly if out in public but it is too
early to state this as fact.

Here it is actually somewhat difficult to tell what may be the most
prevalent type of incidents. It seems like most of the incidents were
indiscriminate or family issues. That said, the amount by which they be
the most is not very high so across the board it looks like most
situations could escalate to this degree.

Not much else to say here however it is worth noting the amount of
bigger zones of injured victims compared to deaths. While it shows more
people were endangered it also shows that there were plenty of survivors
as well which is note worthy. Most of these were indiscriminate but
there are a few others like despondency, terrorism and arson.

# Getting a count of the incidents per state
stateIncidents <- incidents %>%
count(state)
# Setting a fill color variable dependent on the number of incidents
stateIncidents <- stateIncidents %>%
mutate(fillColor = ifelse(n>=40, "40+", ifelse(n>=20, "20-39", "0-19")))
Here are bar graph statistics showcasing all of the incidents from
the data set and showing them from most to least in a bar graph form.
From this we can see that California, Texas and Illinois are the three
most dangerous (in the sense of the most mass murders occurring)
locations in the US. Florida being an honorable mention for fourth
place. From here on I could also then further test to check the amount
of victims, whilst this graph shows the most mass killings in occurrence
for the past ~20 years, that does not necessarily pertain to deadliness
as there may be other states that have less but more severe mass
murders.
One notable mention for these next three graphs is that I left in the
Las Vegas shooting and that is due to the nature of the situation. As of
this day, there is still no verified reason for why the offender did
what he did, however, there has been speculation to what it could be and
a lot of people assume it may have something to do with his gambling.
Las Vegas being essentially the hub of night life, party, gambling, all
of the above, I decided to include it as even though it is an outlier in
this data set, I believe it is still likely enough for another
occurrence to partake if that is the reason to be believed.

# Getting a sum of the amount of both victims killed and injured per state
deadlynessPerState <- incidents %>%
group_by(state) %>%
summarize(totalDeaths = sum(num_victims_killed), totalInjured = sum(num_victims_injured))
# Now applying a manual fill variable to be able to apply to the graph later
deadlynessPerState <- deadlynessPerState %>%
mutate(fillColorDeath = ifelse(totalDeaths>=200, "200+", ifelse(totalDeaths>=100, "100-199", "0-99")),
fillColorInjury = ifelse(totalInjured>=200, "200+", ifelse(totalInjured>=100, "100-199", "0-99")))
And here I checked the amount of deaths per state. The top states
stayed relatively the same however it is worth noting that while
Illinois had more occurrences, it seems that there were more deadly
incidents in Florida as it ended up overtaking Illinois as the 3rd.

Another measurement of deadliness/lethality would be the amount of
injured people. Luckily, this means that everyone here survived the
occurrences yet it also displays how many more people were involved in
the situations leading to more a wide spread problem. What is notable is
that Nevada has overtaken every state my a large margin and this is due
to the aforementioned Las Vegas shooting of 2017. Again, luckily, a lot
of people were able to survive that attack but many were injured, 850+
to be exact. This level of malice could potentially occur again due to
the nature of Las Vegas so it is something to be mindful of and I
believe noteworthy enough to keep in.
Next, Texas and California are the 2nd and 3rd with most injured
victims respectively. Something to be mindful though is that Florida is
5th while also being higher in the other visualizations which could be
inferred as Florida actually being worse as it is possible that it means
that if you are in a mass murder attempt in Florida, you may be less
likely to survive.

This bar graph lets us see what is the most prevalent means of murder
that was used. Some are a little weird to classify as a weapon but what
it means is what was used. This graph actually supports our prior
observation how guns are by far the most prevalent. The usage difference
is staggering, all the others combined do not even add to half of the
usage of weapons.

# Getting rid of N/A
victimsClean <- victims %>%
na.omit()
# Replace empty cells in the situation_type column in incidents with "Unknown"
victimsClean$race[victimsClean$race == ""] <- "Unknown"
victimCountSex <- victimsClean %>%
count(sex)
victimCountRace <- victimsClean%>%
count(race)
With this Violin plot (+ Boxplot) we can see the general distribution
of the victims as well as the medians. Generally it seems that females
and males are both on average not too dissimilar 1497M VS 1656F >
47.5% to 52.5%. Proportionally however, the age of which they died does
not seem to matter despite the sex. The unknown seems to be cases which
the bodies were recovered but maybe not able to be identified as these
cases have little to no information to them
ggplot(victimsClean, aes(x = sex, y = age, fill = sex)) +
geom_violin(trim = TRUE, alpha = 0.9, scale = "width") +
geom_boxplot(width = 0.1) +
theme(legend.position = "none", plot.title = element_text(hjust = 0.5, face = "bold")) +
labs(title = "Showcase Density of Victims' Sex to Age", x = "Sex", y = "Age")

Similar to the violin plot above but this one goes over the race to
age. Unlike the sex one it seems there is some form of disproportion
based on race. Whether this is due to the crime or targetting them is
still too early to say, however, it seems that on average
hispanic/latino and black people are more likely to be a victim in these
mass murders at the average age of ~25. American Indian is around ~30
and Asian/Pacific Islander with White average at around ~35.

I recalled in the past that there was a discriminatory attack at the
gay Orlando night cub named Pulse. This made me wonder if there were any
other discriminatory attacks, while that incident was chalked up to
terrorism, it still was an attack on a location where the target
audience was predominantly gay men. Here I was checking if there are any
other discriminatory attacks against gay people searching through the
narratives for the term “gay”, surprisingly, out of all the ones in the
US only one showed up, which is the same one from above that occurred in
Orlando.
Surprisingly enough, out of the 600+ incidents there were barely any
that specifically were targeting people whether it be for their sexual
orientation or just racism. Of course, this was looking through the
narrative to see if there were any that may not have been included in
the situation_type of “Hate” and the only one not there was the Orlando
Nightclub shooting and this is due to later further evidence of it being
categorized as a terrorist attack as the offender had affiliations to
ISIS.
# With grepl I can search for specific words in the narrative or any other of the strings of texts that give narratives.
incidents %>%
filter(grepl("gay", narrative))
incidents %>%
filter(grepl("lesbian", narrative))
incidents %>%
filter(grepl("queer", narrative))
incidents %>%
filter(grepl(" anti", narrative))
incidents %>%
filter(grepl("LGBT", narrative))
incidents %>%
filter(situation_type == "Hate")
NA
LS0tDQp0aXRsZTogIk1hc3MgTXVyZGVyIFByb2plY3QiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCmF1dGhvcjogIkhhbGFuIEJhZGlsbGEgT3NvcmlvIg0KLS0tDQoNCmBgYHtyfQ0KU3lzLnNldGVudihMQU5HID0gImVuIikNCmBgYA0KDQoNCmBgYHtyfQ0KIyBBbGwgbGlicmFyaWVzLiBJIGRvbid0IHRoaW5rIEkgZW5kZWQgdXAgdXNpbmcgdGhlbSBhbGwgYnV0IEkgZG9uJ3Qgd2FudCB0byBmaW5kIG91dCB3aGljaCBvbmUgSSdtIG5vdCB1c2luZy4NCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShtYXBzKQ0KbGlicmFyeShtYXBwcm9qKQ0KbGlicmFyeSh1c21hcCkNCmxpYnJhcnkoSVNMUjIpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShoZXhiaW4pDQpgYGANCg0KYGBge3J9DQojIENoYW5nZSB3b3JraW5nIGRpcmVjdG9yeSB0byB3aGF0ZXZlciB3b3JrcyBiZXN0IGZvciB5b3UuDQpzZXR3ZCgiQzovVXNlcnMvaGFsYW4vRGVza3RvcC9GUFUvU3ByaW5nMjAyNS9TdGF0aXN0aWNhbExlYXJuaW5nL1NUQTMyNDEtUHJvamVjdC1IYWxhbkJhZGlsbGEtU1AyNS9EYXRhIikNCg0KaW5jaWRlbnRzIDwtIHJlYWQuY3N2KCJtYXNzX2tpbGxpbmdfaW5jaWRlbnRzX3B1YmxpYy5jc3YiKQ0Kb2ZmZW5kZXJzIDwtIHJlYWQuY3N2KCJtYXNzX2tpbGxpbmdfb2ZmZW5kZXJzX3B1YmxpYy5jc3YiKQ0KdmljdGltcyA8LSByZWFkLmNzdigibWFzc19raWxsaW5nX3ZpY3RpbXNfcHVibGljLmNzdiIpDQp3ZWFwb25zIDwtIHJlYWQuY3N2KCJtYXNzX2tpbGxpbmdfd2VhcG9uc19wdWJsaWMuY3N2IikNCmBgYA0KDQpIZXJlIEkgb3BlbiB0aGUgZm91ciBkYXRhIHNldHMgdGhhdCB3ZXJlIHVzZWQuIEFsbCBmb3VyIGFyZSBjb25uZWN0ZWQgd2l0aCBhbiAiaW5jaWRlbnRfaWQiIGFsbG93aW5nIHlvdSB0byBzZWUgd2hhdCBpbmZvcm1hdGlvbiBpcyBjb25uZWN0ZWQuDQoNCmBgYHtyfQ0KIyBTbyB5b3UgY2FuIHZpZXcgdGhlIHRhYmxlcy4NCmluY2lkZW50cw0Kb2ZmZW5kZXJzDQp2aWN0aW1zDQp3ZWFwb25zDQpgYGANCg0KREFUQTogTWFzcyBLaWxsaW5nIERhdGFiYXNlIDIwMDYgLSBQcmVzZW50IChBUyBPRiBNQVJDSCAxNXRoIDIwMjUpDQoNClRoaXMgcHJvamVjdCBtYWtlcyB1c2Ugb2YgZm91ciBkYXRhIHNldHMgd2hpY2ggYXJlIGFsbCBjb25uZWN0ZWQuIEFsbCBmb3VyIGRhdGEgc2V0cyBjb250YWluIGEgY29sdW1uIG5hbWVkICJpbmNpZGVudF9pZCIsIGFuIGlkIHdoaWNoIGxpbmtzIGFsbCBvZiB0aGVtIHRvZ2V0aGVyIHRvIHNlZSB3aGF0IGluZm9ybWF0aW9uIGlzIGNvbm5lY3RlZCB0byB3aGF0Lg0KDQpNYXNzIE11cmRlciBmb3IgdGhpcyBkYXRhIHNldCBpcyBkZWZpbmVkIHVzaW5nIHRoZSBkZWZpbml0aW9uIGdpdmVuIGJ5IHRoZSBGQkk6IA0KIi4uLnRoZSBpbnRlbnRpb25hbCBraWxsaW5nIG9mIGZvdXIgb3IgbW9yZSB2aWN0aW1zIGJ5IGFueSBtZWFucyB3aXRoaW4gYSAyNC1ob3VyIHBlcmlvZCwgZXhjbHVkaW5nIHRoZSBkZWF0aCBvZiB1bmJvcm4gY2hpbGRyZW4gYW5kIHRoZSBvZmZlbmRlcihzKS4pDQoNClRoaXMgRGF0YWJhc2UgaXMgY29uc3RhbnRseSBiZWluZyB1cGRhdGVkIChXYXMganVzdCB1cGRhdGVkIDIgaG91cnMgYWdvIGFzIG9mIE1hcmNoIDE2dGgsIDIwMjUgYXQgMTI6NTBQTSkgYW5kIGlzIHZlcnkgdHJ1c3R3b3J0aHkuIFRoZSBtYWluIGNvbnRhY3QgZm9yIHRoZXNlIGRhdGEgc2V0cyBpcyBKdXN0aW4gTXllcnMuIEp1c3RpbiBNeWVycyBpcyBhIHZldGVyYW4gam91cm5hbGlzdCBmb3IgIlRoZSBBc3NvY2lhdGVkIFByZXNzIiwgdGhleSBhcmUgYWxzbyB3b3JraW5nIHdpdGggTm9ydGhlYXN0ZXJuIFVuaXZlcnNpdHkncyBKYW1lcyBBbGFuIEZveCB3aG9tIGlzIGFsc28gYSBjb250YWN0Lg0KDQpGZWF0dXJlcyhJbmNpZGVudCBbMTkgQ29sdW1ucyB4IDYxNSBSb3dzXSk6DQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPlJlZDwvc3Bhbj4gPSBDYXRlZ29yaWNhbCB8IDxzcGFuIHN0eWxlPSJjb2xvcjpncmVlbiI+R3JlZW48L3NwYW4+ID0gTnVtZXJpY2FsDQoNCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+aW5jaWRlbnRfaWQ8L3NwYW4+OiBJRCBvZiBpbmNpZGVudA0KLSA8c3BhbiBzdHlsZT0iY29sb3I6Z3JlZW4iPmRhdGU8L3NwYW4+OiBEYXRlIG9mIGluY2lkZW50DQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPmNpdHk8L3NwYW4+OiBDaXR5L1Rvd24gbmFtZQ0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5zdGF0ZTwvc3Bhbj46IFN0YXRlIHBvc3RhbCBjb2RlDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpncmVlbiI+bnVtX29mZmVuZGVyczwvc3Bhbj46IE51bWJlciBvZiBvZmZlbmRlcnMNCi0gPHNwYW4gc3R5bGU9ImNvbG9yOmdyZWVuIj5udW1fa2lsbGVkPC9zcGFuPjogTnVtYmVyIG9mIHZpY3RpbXMga2lsbGVkDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpncmVlbiI+bnVtX2luanVyZWQ8L3NwYW4+OiBOdW1uYmVyIG9mIHZpY3RpbXMgaW5qdXJlZA0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5maXJzdGNvZDwvc3Bhbj46IEZpcnN0IGNhdXNlIG9mIGRlYXRoDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPnNlY29uZGNvZDwvc3Bhbj46IFNlY29uZCBjYXVzZSBvZiBkZWF0aA0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5pZl9hc3NhdWx0X3JpZmxlPC9zcGFuPjogV2hldGhlciBhIHJpZmxlIHdhcyB1c2VkDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPnR5cGU8L3NwYW4+OiBUeXBlIG9mIGluY2lkZW50IChpZS4gRmFtaWx5LCBGZWxvbnksIFB1YmxpYywgZXRjLikNCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+c2l0dWF0aW9uX3R5cGU8L3NwYW4+OiBUeXBlIG9mIHNpdHVhdGlvbiAoaWUuIEFyc29uLCBEcnVnIFRyYWRlLCBGYW1pbHkgSXNzdWUsIGV0Yy4pDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPmxvY2F0aW9uX3R5cGU8L3NwYW4+OiBUeXBlIG9mIGxvY2F0aW9uIChpZS4gQ29tbWVyY2lhbC9SZXRhaWwvRW50ZXJ0YWlubWVudCwgR292ZXJubWVudC9UcmFuc2l0LCBIb3VzZSBvZiB3b3JzaGlwLCBldGMuKQ0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5sb2NhdGlvbjwvc3Bhbj46IExvY2F0aW9uIChpZS4gQmFyL0NsdWIvUmVzdGF1cmFudCwgQ29sbGVnZSwgQ29tbWVyY2lhbC9SZXRhaWwsIGV0Yy4pDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpncmVlbiI+bG9uZ2l0dWRlPC9zcGFuPg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6Z3JlZW4iPmxhdGl0dWRlPC9zcGFuPg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5jb3VudHk8L3NwYW4+OiBDb3VudHkgYXNzb2NpYXRlZCB3aXRoIGNvb3JkaW5hdGVzDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpncmVlbiI+Z2VvY29kZTwvc3Bhbj46IEZJUFMgZ2VvY29kZSBvZiBsb2NhdGlvbg0KLSBuYXJyYXRpdmU6IERlc2NyaXB0aW9uIG9mIGluY2lkZW50DQoNCg0KRmVhdHVyZXMoVmljdGltcyBbNiBDb2x1bW5zIHggMzE3NCBSb3dzXSk6DQoNCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+aW5jaWRlbnRfaWQ8L3NwYW4+OiBJRCBmb3IgaW5jaWRlbnQsIHVzZWQgdG8gbGluayB0aGUgdmljdGltcyBkYXRhLg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj52aWN0aW1faWQ8L3NwYW4+OiBJRCBvZiB0aGUgdmljdGltLCBmb3IgcmVjb3JkaW5nIHB1cnBvc2VzLg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6Z3JlZW4iPmFnZTwvc3Bhbj46IEFnZSBvZiB0aGUgdmljdGltLg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5yYWNlPC9zcGFuPg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5zZXg8L3NwYW4+DQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPnZvcmVsYXRpb25zaGlwPC9zcGFuPjogUmVsYXRpb25zaGlwIG9mIHZpY3RpbSB0byB0aGUgb2ZmZW5kZXINCg0KRmVhdHVyZXMoV2VhcG9ucyBbNSBDb2x1bW5zIHggOTYzIFJvd3NdKToNCg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5pbmNpZGVudF9pZDwvc3Bhbj46IElEIGZvciBpbmNpZGVudCwgdXNlZCB0byBsaW5rIHdlYXBvbiB0byBpbmNpZGVudC4NCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+d2VhcG9uX2lkPC9zcGFuPjogSUQgZm9yIHdlYXBvbiBpZGVudGlmaWNhdGlvbi4NCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+d2VhcG9uX3R5cGU8L3NwYW4+OiBUeXBlIG9mIHdlYXBvbi4NCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+Z3VuX2NsYXNzPC9zcGFuPjogQ2xhc3NpZmljYXRpb24gb2YgZ3VuIChIYW5kZ3VuLCBMb25nIGd1biwgVW5rbm93biBndW4gY2xhc3MsIE5vbi1ndW4pDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPmd1bl90eXBlPC9zcGFuPjogVHlwZSBvZiBndW4gKGllLiBIYW5kZ3VuLCBQaXN0b2wsIFJldm9sdmVyLCBSaWZsZSwgZXRjLikNCg0KRmVhdHVyZXMoT2ZmZW5kZXJzIFsxNSBDb2x1bW5zIHggNzg4IFJvd3NdKToNCg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5pbmNpZGVudF9pZDwvc3Bhbj46IElEIG9mIGluY2lkZW50LCB1c2VkIHRvIGNvbm5lY3QgdGhlIDQgZGF0YSBzZXRzLg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5vZmZlbmRlcl9pZDwvc3Bhbj46IElEIHVzZWQgZm9yIGNsYXNzaWZpY2F0aW9uIG9mIG9mZmVuZGVycyAoTW9zdGx5IGZvciBtdWx0aS1vZmZlbmRlciBpbmNpZGVudHMpDQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPmZpcnN0bmFtZTwvc3Bhbj4NCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+bWlkZGxlbmFtZTwvc3Bhbj4NCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+bGFzdG5hbWU8L3NwYW4+DQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPnN1ZmZpeDwvc3Bhbj4NCi0gPHNwYW4gc3R5bGU9ImNvbG9yOmdyZWVuIj5hZ2U8L3NwYW4+DQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPnJhY2U8L3NwYW4+DQotIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPnNleDwvc3Bhbj4NCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+c3VpY2lkZTwvc3Bhbj46IFdoZXRoZXIgdGhlIG9mZmVuZGVyIGNvbW1pdGVkIHN1aWNpZGUgb3Igbm90Lg0KLSA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5kZWF0aGNhdXNlPC9zcGFuPjogV2hhdCBkaWQgdGhlIG9mZmVuZGVyIGRpZSBieSB3aGV0aGVyIGl0IHdhcyBzdWljaWRlIG9yIGtpbGxlZCBieSBhIGJ5c3RhbmRlci9wb2xpY2UNCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+b3V0Y29tZTwvc3Bhbj46IFdoYXQgd2FzIHRoZSBsZWdhbCBvdXRjb21lIGZvciB0aGUgaW5jaWRlbnQgKGllLiBBY3F1aXR0ZWQsIEFycmVzdGVkL1BlbmRpbmcgdHJpYWwsIENoYXJnZXMgZHJvcHBlZCwgZXRjLikNCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+Y3JpbWluYWxfanVzdGljZV9wcm9jZXNzPC9zcGFuPjogU3RhdHVzIG9mIGNyaW1pbmFsIGp1c3RpY2UgcHJvY2VzcyAoaWUuIEFycmVzdGVkL1BlbmRpbmcgdHJpYWwsIGNoYXJnZXMgZHJvcHBlZCwgZXRjLikNCi0gPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+c2VudGVuY2VfdHlwZTwvc3Bhbj46IFR5cGUgb2Ygc2VudGVuY2UgY29udmljdGVkIChpZS4gQWNxdWl0dGVkLCBBd2FpdGluZyBzZW50ZW5jaW5nLCBDb21taXR0ZWQsIERlYXRoIHNlbnRlbmNlIGV0Yy4pDQotIHNlbnRlbmNlX2RldGFpbHM6IERldGFpbHMgYWJvdXQgdGhlIHNlbnRlbmNlIGNvbnZpY3RlZC4NCg0KYGBge3J9DQojIFJlcGxhY2UgZW1wdHkgY2VsbHMgaW4gdGhlIHNpdHVhdGlvbl90eXBlIGNvbHVtbiBpbiBpbmNpZGVudHMgd2l0aCAiVW5rbm93biINCg0KaW5jaWRlbnRzJHNpdHVhdGlvbl90eXBlW2luY2lkZW50cyRzaXR1YXRpb25fdHlwZSA9PSAiIl0gPC0gIlVua25vd24iDQpgYGANCg0KYGBge3J9DQojIFN1YnNldCBmb3IgdHJhbnNmb3JtaW5nIHRoZSBnZW8tZGF0YQ0KdmFySSA8LSBpbmNpZGVudHMgJT4lDQogIHNlbGVjdChjKGluY2lkZW50X2lkLCBsb25naXR1ZGUsIGxhdGl0dWRlLCBmaXJzdGNvZCwgc2l0dWF0aW9uX3R5cGUsIGxvY2F0aW9uLCBudW1fdmljdGltc19raWxsZWQsIG51bV92aWN0aW1zX2luanVyZWQpKSAlPiUNCiAgcmVuYW1lKGxvbiA9IGxvbmdpdHVkZSkgJT4lDQogIHJlbmFtZShsYXQgPSBsYXRpdHVkZSkNCg0KIyBUcmFuc2Zvcm1pbmcgZ2VvLWRhdGEgdG8gYmUgdXNhYmxlIHdpdGggdXNtYXANCnRyYW5zZm9ybWVkRGF0YSA8LSB1c21hcF90cmFuc2Zvcm0odmFySSkNCmBgYA0KDQpGb3IgdGhlIHNha2Ugb2YgdmlzdWFsaXphdGlvbiwgaW5jaWRlbnQgMzQyLCB0aGUgMjAxNyBMYXMgVmVnYXMgc2hvb3RpbmcgaW5jaWRlbnQgd2FzIGV4Y2x1ZGVkIGFzIGl0IGlzIHRvbyBtdWNoIG9mIGFuIG91dGxpZXIgdG8gcHJvcGVybHkgdmlzdWFsaXplIGluZm9ybWF0aW9uLiBUbyBzZWUgdGhlIGRldGFpbHMsIGJlbG93IEkgaGF2ZSBwcm92aWRlZCB0aGUgaW5jaWRlbnQgc28geW91IGNhbiBzZWUgdGhlIGRldGFpbHMuDQoNCmBgYHtyfQ0KIyBTbyBhbnlvbmUgY2FuIHNlZSB0aGUgaW5mb3JtYXRpb24gb24gdGhhdCBldmVudC4NCmluY2lkZW50c1tpbmNpZGVudHMkaW5jaWRlbnRfaWQgPT0gMzQyLCBdDQoNCiMgRmlsdGVyaW5nIHRoZSBvYnNlcnZhdGlvbi4NCnRlbXBEYXRhIDwtIHRyYW5zZm9ybWVkRGF0YSAlPiUNCiAgZmlsdGVyKGluY2lkZW50X2lkICE9IDM0MikNCg0KYGBgDQoNCkZvciB0aGVzZSBmdXR1cmUgdmlzdWFsaXphdGlvbnMgdGhlcmUgd2lsbCBiZSAyLCBvbmUgd2hpY2ggd2lsbCBzaG93IGNhc2UgdGhlIGRlYXRocyB3aGlsZSB0aGUgb3RoZXIgc2hvd2Nhc2VzIHRoZSBhbW91bnQgb2YgaW5qdXJlZCBhbmQgYWxpdmUgc3Vydml2b3JzLg0KRm9yIHRoZXNlIGZpcnN0IHR3bywgdGhlIGRhdGEgY29udGFpbnMgdHdvIGNhdXNlIG9mIGRlYXRoLCB0aGUgZmlyc3QgY2F1c2Ugb2YgZGVhdGggaXMgd2hhdCB3ZSB3aWxsIGZvY3VzIG9uIGJ1dCB0aGUgc2Vjb25kIGNhdXNlIG9mIGRlYXRoIGFyZSBhbnkgb3RoZXIgbWVhbnMgdXNlZCBieSB0aGUgb2ZmZW5kZXJzLiBGb3IgdGhlc2UgdHdvIHZpc3VhbGl6YXRpb25zIG9ubHkgdGhlIHByaW1hcnkgY2F1c2VzIHdpbGwgYmUgdXNlZC4NCg0KSW4gdGhpcyBmaXJzdCBvbmUgd2UgY2FuIHNlZSByYXRoZXIgY2xlYXJseSB0aGF0IHRoZSBsZWFkIGNhdXNlIG9mIGRlYXRocyBpbiBtYXNzIG11cmRlcnMgaXMgc2hvb3RpbmdzLiBUaGUgcnVubmVyIHVwIHRvIHRoaXMgc2VlbXMgdG8gYmUgZWl0aGVyIHN0YWJiaW5nIG9yIGJsdW50IGZvcmNlLiBJbiB0aGlzIGdyYXBoIGFuZCB3aGF0IHlvdSB3aWxsIG5vdGljZSBpbiB0aGUgb3RoZXIgZ3JhcGhzIGFzIHdlbGwgaXMgdGhhdCBpbiBnZW5lcmFsIHRoZSBtaWQgd2VzdCBpcyB0aGUgbXVjaCBzYWZlciBhcmVhIHJlbGF0aXZlbHkuIFRoZSBlYXN0IGNvYXN0IHNwZWNpZmljYWxseSBpcyBzdHJld24gd2l0aCBtYXNzIG11cmRlcnMgb2YgbXVsdGlwbGUgZGlmZmVyZW50IGRlZ3JlZXMuDQoNCmBgYHtyLCBmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDEwfQ0KcGxvdF91c21hcCgpICsgZ2VvbV9zZigNCiAgZGF0YSA9IHRlbXBEYXRhLA0KICBhZXMoY29sb3IgPSBmaXJzdGNvZCwgc2l6ZSA9IG51bV92aWN0aW1zX2tpbGxlZCksDQogIGFscGhhID0gLjUpICsNCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMiwxMCkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLmtleS5zaXplID0gdW5pdCg2LCAnbW0nKSwgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpICsNCiAgbGFicyh0aXRsZSA9ICJQcmltYXJ5IFJlYXNvbiBmb3IgVmljdGltIERlYXRocyIsIGNhcHRpb24gPSAiLVRoZSAyMDE3IExhcyBWZWdhcyBTaG9vdGVyIGhhcyBiZWVuIGV4Y2x1ZGVkIGZvciBjbGFyaXR5LiBUaGF0IGV2ZW50IGhhZCA2MCBkZWF0aHMgYW5kIDg2NyBpbmp1cmVkLiIsIGNvbG9yID0gIkZpcnN0IENhdXNlIG9mIERlYXRoIiwgc2l6ZSA9ICJBbW91bnQgb2YgVmljdGltcyBNdXJkZXJlZCIpDQoNCmBgYA0KVGhpcyB2aXN1YWxpemF0aW9uIGlzIHNpbWlsYXIgdG8gdGhlIGxhc3QgZXhjZXB0IGl0IHNob3cgY2FzZXMgdGhlIGFtb3VudCBvZiBpbmp1cmVkIHZpY3RpbXMuIFRoaXMgbWVhbnMgYW55IHZpY3RpbXMgdGhhdCB3ZXJlIHBhcnQgb2YgdGhlIG1hc3MgbXVyZGVyIGF0dGVtcHQgYW5kIHN1cnZpdmVkIHdpdGggaW5qdXJpZXMuICBTaW1pbGFyIHRvIHRoZSBsYXN0LCBhIGxhcmdlIHBvcnRpb24gb2YgdGhlc2UgY29ycmVsYXRlIHdpdGggdGhlIGRlYXRocywgcGxlbnR5IG9mIGluY2lkZW50cyBvY2N1cmluZyBpbiB0aGUgZWFzdCwgd2VzdCBhbmQgY2VudHJhbCBVUyB5ZXQgdGhlIG1vdW50YWluZW91cy9taWR3ZXN0IGlzIG11Y2ggbW9yZSBiYXJyZW4gaW4gY29tcGFyaXNvbi4gVGhpcyBjb3VsZCBiZSBhIHBvcnRyYXlhbCBvZiBzaW1wbHkgdGhlIHBvcHVsYXRpb24gdG8gaW5jaWRlbnRzIGJ1dCBhcyBJIGRvIG5vdCBoYXZlIHBvcHVsYXRpb24gZGF0YSBpdCBpcyBoYXJkIHRvIGNvbmZpcm0gdGhhdC4gDQoNCmBgYHtyLCBmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDEwfQ0KcGxvdF91c21hcCgpICsgZ2VvbV9zZigNCiAgZGF0YSA9IHRlbXBEYXRhLA0KICBhZXMoY29sb3IgPSBmaXJzdGNvZCwgc2l6ZSA9IG51bV92aWN0aW1zX2luanVyZWQpLA0KICBhbHBoYSA9IC41KSArDQogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDIsMTApKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoNiwgJ21tJyksIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKSArDQogIGxhYnModGl0bGUgPSAiUHJpbWFyeSBSZWFzb24gZm9yIEluanVyZWQgVmljdGltcyIsIGNhcHRpb24gPSAiLVRoZSAyMDE3IExhcyBWZWdhcyBTaG9vdGVyIGhhcyBiZWVuIGV4Y2x1ZGVkIGZvciBjbGFyaXR5LiBUaGF0IGV2ZW50IGhhZCA2MCBkZWF0aHMgYW5kIDg2NyBpbmp1cmVkLiIsIGNvbG9yID0gIkZpcnN0IENhdXNlIG9mIERlYXRoIiwgc2l6ZSA9ICJOdW1iZXIgb2YgSW5qdXJlZCBWaWN0aW1zIikNCg0KYGBgDQoNCk5leHQgaXMgdGhlIGxvY2F0aW9ucyBpbiB3aGljaCB0aGVzZSBpbmNpZGVudHMgdG9vayBwbGFjZS4gUHJlZG9taW5hbnRseSBpdCBzZWVtcyBsaWtlIHRoZSBtYWpvcml0eSBvZiBtYXNzIG11cmRlcnMgb2NjdXJyZWQgaW4gcmVzaWRlbmNlcyB3aGlsZSB0aGUgbmV4dCBjbG9zZXN0IGJlaW5nIGluIHVuaXZlcnNpdGllcyBvciBzY2hvb2xzLiBOZXh0IGl0IGFsc28gc2VlbXMgbGlrZSBiYXJzL2NsdWJzL3Jlc3RhdXJhbnRzIGFyZSBuZXh0IG1ha2luZyBtZSBiZWxpZXZlIHRoYXQgbWF5YmUgdGhlcmUgaXMgYSBkaXNwcm9wb3J0aW9uYXRlIGFtb3VudCBvZiB2aWN0aW1zIHRoYXQgbWF5IGJlIGluIGVpdGhlciBpbiB0aGVyZSAyMHMgdG8gMzBzLCBhcm91bmQgdGhlIGFnZSB5b3UgYXJlIHN0aWxsIGluIHNjaG9vbCBhbmQvb3IgZ29pbmcgb3V0IHdpdGggZnJpZW5kcyAoY2x1YmJpbmcsIGVhdGluZywgZHJpbmtpbmcsIGV0Yy4pDQoNCmBgYHtyLCBmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDEwfQ0KcGxvdF91c21hcCgpICsgZ2VvbV9zZigNCiAgZGF0YSA9IHRlbXBEYXRhLA0KICBhZXMoY29sb3IgPSBsb2NhdGlvbiwgc2l6ZSA9IG51bV92aWN0aW1zX2tpbGxlZCksDQogIGFscGhhID0gLjUpICsNCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMiwxMCkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLmtleS5zaXplID0gdW5pdCg2LCAnbW0nKSwgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpICsNCiAgbGFicyh0aXRsZSA9ICJMb2NhdGlvbiBhbmQgQW1vdW50IG9mIFZpY3RpbSBEZWF0aHMiLCBjYXB0aW9uID0gIi1UaGUgMjAxNyBMYXMgVmVnYXMgU2hvb3RlciBoYXMgYmVlbiBleGNsdWRlZCBmb3IgY2xhcml0eS4gVGhhdCBldmVudCBoYWQgNjAgZGVhdGhzIGFuZCA4NjcgaW5qdXJlZC4iLCBjb2xvciA9ICJMb2NhdGlvbiIsIHNpemUgPSAiTnVtYmVyIG9mIE11cmRlcmVkIFZpY3RpbXMiKQ0KYGBgDQpXaXRoIHdoYXQgeW91IGNhbiBzZWUgaW4gdGhpcyB2aXN1YWxpemF0aW9uIG9mIHRoZSBzdXJ2aXZpbmcgdmljdGltcywgcmVzaWRlbmNlcyBzdGlsbCBkb21pbmF0ZSB3aXRoIHNoZWVyIGFtb3VudCwgaG93ZXZlciwgdGhpcyBhbHNvIHNob3djYXNlcyB0aGF0IGEgbG90IG1vcmUgcGVvcGxlIGFyZSBzdXJ2aXZpbmcgbWFzcyBtdXJkZXIgYXR0ZW1wdHMgaW4gZ2VuZXJhbCBhbmQgbm90IGp1c3QgaW4gcmVzaWRlbmNlcy4gT25lIG1heSBjb25jbHVkZSB0aGF0IHlvdXIgY2hhbmNlcyBvZiBzdXJ2aXZpbmcgbWF5IGdvIHVwIHNpZ25pZmljYW50bHkgaWYgb3V0IGluIHB1YmxpYyBidXQgaXQgaXMgdG9vIGVhcmx5IHRvIHN0YXRlIHRoaXMgYXMgZmFjdC4NCg0KYGBge3IsIGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gMTB9DQpwbG90X3VzbWFwKCkgKyBnZW9tX3NmKA0KICBkYXRhID0gdGVtcERhdGEsDQogIGFlcyhjb2xvciA9IGxvY2F0aW9uLCBzaXplID0gbnVtX3ZpY3RpbXNfaW5qdXJlZCksDQogIGFscGhhID0gLjUpICsNCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMiwxMCkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLmtleS5zaXplID0gdW5pdCg2LCAnbW0nKSwgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpICsNCiAgbGFicyh0aXRsZSA9ICJMb2NhdGlvbiBhbmQgQW1vdW50IG9mIEluanVyZWQgVmljdGltcyIsIGNhcHRpb24gPSAiLVRoZSAyMDE3IExhcyBWZWdhcyBTaG9vdGVyIGhhcyBiZWVuIGV4Y2x1ZGVkIGZvciBjbGFyaXR5LiBUaGF0IGV2ZW50IGhhZCA2MCBkZWF0aHMgYW5kIDg2NyBpbmp1cmVkLiIsIGNvbG9yID0gIkxvY2F0aW9uIiwgc2l6ZSA9ICJBbW91bnQgb2YgSW5qdXJlZCBWaWN0aW1zIikNCmBgYA0KSGVyZSBpdCBpcyBhY3R1YWxseSBzb21ld2hhdCBkaWZmaWN1bHQgdG8gdGVsbCB3aGF0IG1heSBiZSB0aGUgbW9zdCBwcmV2YWxlbnQgdHlwZSBvZiBpbmNpZGVudHMuIEl0IHNlZW1zIGxpa2UgbW9zdCBvZiB0aGUgaW5jaWRlbnRzIHdlcmUgaW5kaXNjcmltaW5hdGUgb3IgZmFtaWx5IGlzc3Vlcy4gVGhhdCBzYWlkLCB0aGUgYW1vdW50IGJ5IHdoaWNoIHRoZXkgYmUgdGhlIG1vc3QgaXMgbm90IHZlcnkgaGlnaCBzbyBhY3Jvc3MgdGhlIGJvYXJkIGl0IGxvb2tzIGxpa2UgbW9zdCBzaXR1YXRpb25zIGNvdWxkIGVzY2FsYXRlIHRvIHRoaXMgZGVncmVlLiANCg0KYGBge3IsIGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gMTB9DQpwbG90X3VzbWFwKCkgKyBnZW9tX3NmKA0KICBkYXRhID0gdGVtcERhdGEsDQogIGFlcyhjb2xvciA9IHNpdHVhdGlvbl90eXBlLCBzaXplID0gbnVtX3ZpY3RpbXNfa2lsbGVkKSwNCiAgYWxwaGEgPSAwLjgpICsNCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMiwxMCkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLmtleS5zaXplID0gdW5pdCg2LCAnbW0nKSwgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpICsNCiAgbGFicyh0aXRsZSA9ICJUeXBlIG9mIEluY2lkZW50IGFuZCBBbW91bnQgb2YgVmljdGltIERlYXRocyIsIGNhcHRpb24gPSAiLVRoZSAyMDE3IExhcyBWZWdhcyBTaG9vdGVyIGhhcyBiZWVuIGV4Y2x1ZGVkIGZvciBjbGFyaXR5LiBUaGF0IGV2ZW50IGhhZCA2MCBkZWF0aHMgYW5kIDg2NyBpbmp1cmVkLiIsIGNvbG9yID0gIlR5cGUgb2YgU2l0dWF0aW9uIiwgc2l6ZSA9ICJBbW91bnQgb2YgTXVyZGVyZWQgVmljdGltcyIpDQoNCmBgYA0KTm90IG11Y2ggZWxzZSB0byBzYXkgaGVyZSBob3dldmVyIGl0IGlzIHdvcnRoIG5vdGluZyB0aGUgYW1vdW50IG9mIGJpZ2dlciB6b25lcyBvZiBpbmp1cmVkIHZpY3RpbXMgY29tcGFyZWQgdG8gZGVhdGhzLiBXaGlsZSBpdCBzaG93cyBtb3JlIHBlb3BsZSB3ZXJlIGVuZGFuZ2VyZWQgaXQgYWxzbyBzaG93cyB0aGF0IHRoZXJlIHdlcmUgcGxlbnR5IG9mIHN1cnZpdm9ycyBhcyB3ZWxsIHdoaWNoIGlzIG5vdGUgd29ydGh5LiBNb3N0IG9mIHRoZXNlIHdlcmUgaW5kaXNjcmltaW5hdGUgYnV0IHRoZXJlIGFyZSBhIGZldyBvdGhlcnMgbGlrZSBkZXNwb25kZW5jeSwgdGVycm9yaXNtIGFuZCBhcnNvbi4NCg0KYGBge3IsIGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gMTB9DQpwbG90X3VzbWFwKCkgKyBnZW9tX3NmKA0KICBkYXRhID0gdGVtcERhdGEsDQogIGFlcyhjb2xvciA9IHNpdHVhdGlvbl90eXBlLCBzaXplID0gbnVtX3ZpY3RpbXNfaW5qdXJlZCksDQogIGFscGhhID0gMC44KSArDQogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDIsMTApKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoNiwgJ21tJyksIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKSArDQogIGxhYnModGl0bGUgPSAiVHlwZSBvZiBJbmNpZGVudCBhbmQgQW1vdW50IG9mIEluanVyZWQgVmljdGltcyIsIGNhcHRpb24gPSAiLVRoZSAyMDE3IExhcyBWZWdhcyBTaG9vdGVyIGhhcyBiZWVuIGV4Y2x1ZGVkIGZvciBjbGFyaXR5LiBUaGF0IGV2ZW50IGhhZCA2MCBkZWF0aHMgYW5kIDg2NyBpbmp1cmVkLiIsIGNvbG9yID0gIlR5cGUgb2YgU2l0dWF0aW9uIiwgc2l6ZSA9ICJOdW1iZXIgb2YgSW5qdXJlZCBWaWN0aW1zIikNCg0KYGBgDQoNCg0KYGBge3J9DQojIEdldHRpbmcgYSBjb3VudCBvZiB0aGUgaW5jaWRlbnRzIHBlciBzdGF0ZQ0Kc3RhdGVJbmNpZGVudHMgPC0gaW5jaWRlbnRzICU+JQ0KICBjb3VudChzdGF0ZSkNCg0KIyBTZXR0aW5nIGEgZmlsbCBjb2xvciB2YXJpYWJsZSBkZXBlbmRlbnQgb24gdGhlIG51bWJlciBvZiBpbmNpZGVudHMNCnN0YXRlSW5jaWRlbnRzIDwtIHN0YXRlSW5jaWRlbnRzICU+JQ0KICBtdXRhdGUoZmlsbENvbG9yID0gaWZlbHNlKG4+PTQwLCAiNDArIiwgaWZlbHNlKG4+PTIwLCAiMjAtMzkiLCAiMC0xOSIpKSkNCmBgYA0KDQpIZXJlIGFyZSBiYXIgZ3JhcGggc3RhdGlzdGljcyBzaG93Y2FzaW5nIGFsbCBvZiB0aGUgaW5jaWRlbnRzIGZyb20gdGhlIGRhdGEgc2V0IGFuZCBzaG93aW5nIHRoZW0gZnJvbSBtb3N0IHRvIGxlYXN0IGluIGEgYmFyIGdyYXBoIGZvcm0uIEZyb20gdGhpcyB3ZSBjYW4gc2VlIHRoYXQgQ2FsaWZvcm5pYSwgVGV4YXMgYW5kIElsbGlub2lzIGFyZSB0aGUgdGhyZWUgbW9zdCBkYW5nZXJvdXMgKGluIHRoZSBzZW5zZSBvZiB0aGUgbW9zdCBtYXNzIG11cmRlcnMgb2NjdXJyaW5nKSBsb2NhdGlvbnMgaW4gdGhlIFVTLiBGbG9yaWRhIGJlaW5nIGFuIGhvbm9yYWJsZSBtZW50aW9uIGZvciBmb3VydGggcGxhY2UuIEZyb20gaGVyZSBvbiBJIGNvdWxkIGFsc28gdGhlbiBmdXJ0aGVyIHRlc3QgdG8gY2hlY2sgdGhlIGFtb3VudCBvZiB2aWN0aW1zLCB3aGlsc3QgdGhpcyBncmFwaCBzaG93cyB0aGUgbW9zdCBtYXNzIGtpbGxpbmdzIGluIG9jY3VycmVuY2UgZm9yIHRoZSBwYXN0IH4yMCB5ZWFycywgdGhhdCBkb2VzIG5vdCBuZWNlc3NhcmlseSBwZXJ0YWluIHRvIGRlYWRsaW5lc3MgYXMgdGhlcmUgbWF5IGJlIG90aGVyIHN0YXRlcyB0aGF0IGhhdmUgbGVzcyBidXQgbW9yZSBzZXZlcmUgbWFzcyBtdXJkZXJzLg0KDQpPbmUgbm90YWJsZSBtZW50aW9uIGZvciB0aGVzZSBuZXh0IHRocmVlIGdyYXBocyBpcyB0aGF0IEkgbGVmdCBpbiB0aGUgTGFzIFZlZ2FzIHNob290aW5nIGFuZCB0aGF0IGlzIGR1ZSB0byB0aGUgbmF0dXJlIG9mIHRoZSBzaXR1YXRpb24uIEFzIG9mIHRoaXMgZGF5LCB0aGVyZSBpcyBzdGlsbCBubyB2ZXJpZmllZCByZWFzb24gZm9yIHdoeSB0aGUgb2ZmZW5kZXIgZGlkIHdoYXQgaGUgZGlkLCBob3dldmVyLCB0aGVyZSBoYXMgYmVlbiBzcGVjdWxhdGlvbiB0byB3aGF0IGl0IGNvdWxkIGJlIGFuZCBhIGxvdCBvZiBwZW9wbGUgYXNzdW1lIGl0IG1heSBoYXZlIHNvbWV0aGluZyB0byBkbyB3aXRoIGhpcyBnYW1ibGluZy4gTGFzIFZlZ2FzIGJlaW5nIGVzc2VudGlhbGx5IHRoZSBodWIgb2YgbmlnaHQgbGlmZSwgcGFydHksIGdhbWJsaW5nLCBhbGwgb2YgdGhlIGFib3ZlLCBJIGRlY2lkZWQgdG8gaW5jbHVkZSBpdCBhcyBldmVuIHRob3VnaCBpdCBpcyBhbiBvdXRsaWVyIGluIHRoaXMgZGF0YSBzZXQsIEkgYmVsaWV2ZSBpdCBpcyBzdGlsbCBsaWtlbHkgZW5vdWdoIGZvciBhbm90aGVyIG9jY3VycmVuY2UgdG8gcGFydGFrZSBpZiB0aGF0IGlzIHRoZSByZWFzb24gdG8gYmUgYmVsaWV2ZWQuDQoNCmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDEwfQ0KIyBDcmVhdGluZyB0aGUgZ3JhcGggYW5kIG9yZ2FuaXppbmcgYnkgYW1vdW50DQpnZ3Bsb3Qoc3RhdGVJbmNpZGVudHMsIGFlcyh4ID0gcmVvcmRlcihzdGF0ZSwgK24pLCB5ID0gbiwgZmlsbCA9IGZpbGxDb2xvcikpICsgDQogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCB3aWR0aCA9IDAuOCkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBoanVzdCA9IC0uMjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiMC0xOSIgPSAiZ29sZCIsICIyMC0zOSIgPSAib3JhbmdlIiwgIjQwKyIgPSAicmVkIikpICsNCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMywgZmFjZSA9ICJib2xkIiksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGZhY2UgPSAiYm9sZCIpKSArDQogIGxhYnModGl0bGUgPSAiVG90YWwgSW5jaWRlbnRzIFBlciBTdGF0ZSIsIHggPSAiU3RhdGVzIiwgeSA9ICJBbW91bnQgb2YgSW5jaWRlbnRzIiwgZmlsbCA9ICJJbmNpZGVudCBSYW5nZXMiKSArDQogIGNvb3JkX2ZsaXAoKQ0KYGBgDQpgYGB7cn0NCiMgR2V0dGluZyBhIHN1bSBvZiB0aGUgYW1vdW50IG9mIGJvdGggdmljdGltcyBraWxsZWQgYW5kIGluanVyZWQgcGVyIHN0YXRlDQpkZWFkbHluZXNzUGVyU3RhdGUgPC0gaW5jaWRlbnRzICU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcml6ZSh0b3RhbERlYXRocyA9IHN1bShudW1fdmljdGltc19raWxsZWQpLCB0b3RhbEluanVyZWQgPSBzdW0obnVtX3ZpY3RpbXNfaW5qdXJlZCkpDQoNCiMgTm93IGFwcGx5aW5nIGEgbWFudWFsIGZpbGwgdmFyaWFibGUgdG8gYmUgYWJsZSB0byBhcHBseSB0byB0aGUgZ3JhcGggbGF0ZXINCmRlYWRseW5lc3NQZXJTdGF0ZSA8LSBkZWFkbHluZXNzUGVyU3RhdGUgJT4lDQogIG11dGF0ZShmaWxsQ29sb3JEZWF0aCA9IGlmZWxzZSh0b3RhbERlYXRocz49MjAwLCAiMjAwKyIsIGlmZWxzZSh0b3RhbERlYXRocz49MTAwLCAiMTAwLTE5OSIsICIwLTk5IikpLA0KICAgICAgICAgZmlsbENvbG9ySW5qdXJ5ID0gaWZlbHNlKHRvdGFsSW5qdXJlZD49MjAwLCAiMjAwKyIsIGlmZWxzZSh0b3RhbEluanVyZWQ+PTEwMCwgIjEwMC0xOTkiLCAiMC05OSIpKSkNCmBgYA0KDQpBbmQgaGVyZSBJIGNoZWNrZWQgdGhlIGFtb3VudCBvZiBkZWF0aHMgcGVyIHN0YXRlLiBUaGUgdG9wIHN0YXRlcyBzdGF5ZWQgcmVsYXRpdmVseSB0aGUgc2FtZSBob3dldmVyIGl0IGlzIHdvcnRoIG5vdGluZyB0aGF0IHdoaWxlIElsbGlub2lzIGhhZCBtb3JlIG9jY3VycmVuY2VzLCBpdCBzZWVtcyB0aGF0IHRoZXJlIHdlcmUgbW9yZSBkZWFkbHkgaW5jaWRlbnRzIGluIEZsb3JpZGEgYXMgaXQgZW5kZWQgdXAgb3ZlcnRha2luZyBJbGxpbm9pcyBhcyB0aGUgM3JkLg0KDQpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSAxMH0NCmdncGxvdChkZWFkbHluZXNzUGVyU3RhdGUsIGFlcyh4ID0gcmVvcmRlcihzdGF0ZSwgK3RvdGFsRGVhdGhzKSwgeSA9IHRvdGFsRGVhdGhzLCBmaWxsID0gZmlsbENvbG9yRGVhdGgpKSArDQogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCB3aWR0aCA9IDAuOSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdG90YWxEZWF0aHMpLCBoanVzdCA9IC0uMjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiMC05OSIgPSAiZ29sZCIsICIxMDAtMTk5IiA9ICJvcmFuZ2UiLCAiMjAwKyIgPSAicmVkIikpICsNCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMywgZmFjZSA9ICJib2xkIiksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGZhY2UgPSAiYm9sZCIpKSArDQogIGxhYnModGl0bGUgPSAiVG90YWwgVmljdGltcyBNdXJkZXJlZCBQZXIgU3RhdGUiLCB4ID0gIlN0YXRlcyIsIHkgPSAiQW1vdW50IE11cmRlcmVkIiwgZmlsbCA9ICJEZWF0aCBSYW5nZXMiKSArDQogIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCkFub3RoZXIgbWVhc3VyZW1lbnQgb2YgZGVhZGxpbmVzcy9sZXRoYWxpdHkgd291bGQgYmUgdGhlIGFtb3VudCBvZiBpbmp1cmVkIHBlb3BsZS4gTHVja2lseSwgdGhpcyBtZWFucyB0aGF0IGV2ZXJ5b25lIGhlcmUgc3Vydml2ZWQgdGhlIG9jY3VycmVuY2VzIHlldCBpdCBhbHNvIGRpc3BsYXlzIGhvdyBtYW55IG1vcmUgcGVvcGxlIHdlcmUgaW52b2x2ZWQgaW4gdGhlIHNpdHVhdGlvbnMgbGVhZGluZyB0byBtb3JlIGEgd2lkZSBzcHJlYWQgcHJvYmxlbS4gV2hhdCBpcyBub3RhYmxlIGlzIHRoYXQgTmV2YWRhIGhhcyBvdmVydGFrZW4gZXZlcnkgc3RhdGUgbXkgYSBsYXJnZSBtYXJnaW4gYW5kIHRoaXMgaXMgZHVlIHRvIHRoZSBhZm9yZW1lbnRpb25lZCBMYXMgVmVnYXMgc2hvb3Rpbmcgb2YgMjAxNy4gQWdhaW4sIGx1Y2tpbHksIGEgbG90IG9mIHBlb3BsZSB3ZXJlIGFibGUgdG8gc3Vydml2ZSB0aGF0IGF0dGFjayBidXQgbWFueSB3ZXJlIGluanVyZWQsIDg1MCsgdG8gYmUgZXhhY3QuIFRoaXMgbGV2ZWwgb2YgbWFsaWNlIGNvdWxkIHBvdGVudGlhbGx5IG9jY3VyIGFnYWluIGR1ZSB0byB0aGUgbmF0dXJlIG9mIExhcyBWZWdhcyBzbyBpdCBpcyBzb21ldGhpbmcgdG8gYmUgbWluZGZ1bCBvZiBhbmQgSSBiZWxpZXZlIG5vdGV3b3J0aHkgZW5vdWdoIHRvIGtlZXAgaW4uIA0KDQpOZXh0LCBUZXhhcyBhbmQgQ2FsaWZvcm5pYSBhcmUgdGhlIDJuZCBhbmQgM3JkIHdpdGggbW9zdCBpbmp1cmVkIHZpY3RpbXMgcmVzcGVjdGl2ZWx5LiBTb21ldGhpbmcgdG8gYmUgbWluZGZ1bCB0aG91Z2ggaXMgdGhhdCBGbG9yaWRhIGlzIDV0aCB3aGlsZSBhbHNvIGJlaW5nIGhpZ2hlciBpbiB0aGUgb3RoZXIgdmlzdWFsaXphdGlvbnMgd2hpY2ggY291bGQgYmUgaW5mZXJyZWQgYXMgRmxvcmlkYSBhY3R1YWxseSBiZWluZyB3b3JzZSBhcyBpdCBpcyBwb3NzaWJsZSB0aGF0IGl0IG1lYW5zIHRoYXQgaWYgeW91IGFyZSBpbiBhIG1hc3MgbXVyZGVyIGF0dGVtcHQgaW4gRmxvcmlkYSwgeW91IG1heSBiZSBsZXNzIGxpa2VseSB0byBzdXJ2aXZlLg0KDQpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSAxMH0NCmdncGxvdChkZWFkbHluZXNzUGVyU3RhdGUsIGFlcyh4ID0gcmVvcmRlcihzdGF0ZSwgK3RvdGFsSW5qdXJlZCksIHkgPSB0b3RhbEluanVyZWQsIGZpbGwgPSBmaWxsQ29sb3JJbmp1cnkpKSArDQogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCB3aWR0aCA9IDAuOSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdG90YWxJbmp1cmVkKSwgaGp1c3QgPSAtLjI1KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIjAtOTkiID0gImdvbGQiLCAiMTAwLTE5OSIgPSAib3JhbmdlIiwgIjIwMCsiID0gInJlZCIpKSArDQogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGZhY2UgPSAiYm9sZCIpLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAwLjUpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMyksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzLCBmYWNlID0gImJvbGQiKSkgKw0KICBsYWJzKHRpdGxlID0gIlRvdGFsIEluanVyZWQgVmljdGltcyBQZXIgU3RhdGUiLCB4ID0gIlN0YXRlcyIsIHkgPSAiQW1vdW50IG9mIEluanVyZWQiLCBmaWxsID0gIkluanVyeSBSYW5nZXMiKSArDQogIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCmBgYHtyfQ0KIyBHZXR0aW5nIGEgY291bnQgb2YgdGhlIGluY2lkZW50cyBwZXIgc3RhdGUNCndlYXBvbkNvdW50IDwtIHdlYXBvbnMgJT4lDQogIGNvdW50KHdlYXBvbl90eXBlKQ0KDQojIFNldHRpbmcgYSBmaWxsIGNvbG9yIHZhcmlhYmxlIGRlcGVuZGVudCBvbiB0aGUgbnVtYmVyIG9mIGluY2lkZW50cw0Kc3RhdGVJbmNpZGVudHMgPC0gc3RhdGVJbmNpZGVudHMgJT4lDQogIG11dGF0ZShmaWxsQ29sb3IgPSBpZmVsc2Uobj49NDAsICI0MCsiLCBpZmVsc2Uobj49MjAsICIyMC0zOSIsICIwLTE5IikpKQ0KYGBgDQoNClRoaXMgYmFyIGdyYXBoIGxldHMgdXMgc2VlIHdoYXQgaXMgdGhlIG1vc3QgcHJldmFsZW50IG1lYW5zIG9mIG11cmRlciB0aGF0IHdhcyB1c2VkLiBTb21lIGFyZSBhIGxpdHRsZSB3ZWlyZCB0byBjbGFzc2lmeSBhcyBhIHdlYXBvbiBidXQgd2hhdCBpdCBtZWFucyBpcyB3aGF0IHdhcyB1c2VkLiBUaGlzIGdyYXBoIGFjdHVhbGx5IHN1cHBvcnRzIG91ciBwcmlvciBvYnNlcnZhdGlvbiBob3cgZ3VucyBhcmUgYnkgZmFyIHRoZSBtb3N0IHByZXZhbGVudC4gVGhlIHVzYWdlIGRpZmZlcmVuY2UgaXMgc3RhZ2dlcmluZywgYWxsIHRoZSBvdGhlcnMgY29tYmluZWQgZG8gbm90IGV2ZW4gYWRkIHRvIGhhbGYgb2YgdGhlIHVzYWdlIG9mIHdlYXBvbnMuDQoNCmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDV9DQpnZ3Bsb3Qod2VhcG9uQ291bnQsIGFlcyh4ID0gcmVvcmRlcih3ZWFwb25fdHlwZSwgK24pLCB5ID0gbiwgZmlsbCA9IHdlYXBvbl90eXBlKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjkpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBoanVzdCA9IC0uMjUpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKHRpdGxlID0gIlRvdGFsIEFtb3VudCBvZiBXZWFwb24gVHlwZXMgVXNlZCIsIHggPSAiV2VhcG9uIFR5cGUiLCB5ID0gIkNvdW50IikgKw0KICBjb29yZF9mbGlwKCkNCmBgYA0KDQoNCg0KYGBge3J9DQojIEdldHRpbmcgcmlkIG9mIE4vQQ0KdmljdGltc0NsZWFuIDwtIHZpY3RpbXMgJT4lDQogIG5hLm9taXQoKQ0KDQojIFJlcGxhY2UgZW1wdHkgY2VsbHMgaW4gdGhlIHNpdHVhdGlvbl90eXBlIGNvbHVtbiBpbiBpbmNpZGVudHMgd2l0aCAiVW5rbm93biINCnZpY3RpbXNDbGVhbiRyYWNlW3ZpY3RpbXNDbGVhbiRyYWNlID09ICIiXSA8LSAiVW5rbm93biINCmBgYA0KDQpgYGB7cn0NCnZpY3RpbUNvdW50U2V4IDwtIHZpY3RpbXNDbGVhbiAlPiUNCiAgY291bnQoc2V4KSANCg0KdmljdGltQ291bnRSYWNlIDwtIHZpY3RpbXNDbGVhbiU+JQ0KICBjb3VudChyYWNlKQ0KYGBgDQoNCldpdGggdGhpcyBWaW9saW4gcGxvdCAoKyBCb3hwbG90KSB3ZSBjYW4gc2VlIHRoZSBnZW5lcmFsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgdmljdGltcyBhcyB3ZWxsIGFzIHRoZSBtZWRpYW5zLiBHZW5lcmFsbHkgaXQgc2VlbXMgdGhhdCBmZW1hbGVzIGFuZCBtYWxlcyBhcmUgYm90aCBvbiBhdmVyYWdlIG5vdCB0b28gZGlzc2ltaWxhciAxNDk3TSBWUyAxNjU2RiA+IDQ3LjUlIHRvIDUyLjUlLiBQcm9wb3J0aW9uYWxseSBob3dldmVyLCB0aGUgYWdlIG9mIHdoaWNoIHRoZXkgZGllZCBkb2VzIG5vdCBzZWVtIHRvIG1hdHRlciBkZXNwaXRlIHRoZSBzZXguIFRoZSB1bmtub3duIHNlZW1zIHRvIGJlIGNhc2VzIHdoaWNoIHRoZSBib2RpZXMgd2VyZSByZWNvdmVyZWQgYnV0IG1heWJlIG5vdCBhYmxlIHRvIGJlIGlkZW50aWZpZWQgYXMgdGhlc2UgY2FzZXMgaGF2ZSBsaXR0bGUgdG8gbm8gaW5mb3JtYXRpb24gdG8gdGhlbQ0KDQpgYGB7ciwgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDV9DQpnZ3Bsb3QodmljdGltc0NsZWFuLCBhZXMoeCA9IHNleCwgeSA9IGFnZSwgZmlsbCA9IHNleCkpICsNCiAgZ2VvbV92aW9saW4odHJpbSA9IFRSVUUsIGFscGhhID0gMC45LCBzY2FsZSA9ICJ3aWR0aCIpICsNCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4xKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpICsNCiAgbGFicyh0aXRsZSA9ICJTaG93Y2FzZSBEZW5zaXR5IG9mIFZpY3RpbXMnIFNleCB0byBBZ2UiLCB4ID0gIlNleCIsIHkgPSAiQWdlIikNCmBgYA0KDQpgYGB7cn0NCnZpY3RpbUNvdW50U2V4DQpgYGANClNpbWlsYXIgdG8gdGhlIHZpb2xpbiBwbG90IGFib3ZlIGJ1dCB0aGlzIG9uZSBnb2VzIG92ZXIgdGhlIHJhY2UgdG8gYWdlLiBVbmxpa2UgdGhlIHNleCBvbmUgaXQgc2VlbXMgdGhlcmUgaXMgc29tZSBmb3JtIG9mIGRpc3Byb3BvcnRpb24gYmFzZWQgb24gcmFjZS4gV2hldGhlciB0aGlzIGlzIGR1ZSB0byB0aGUgY3JpbWUgb3IgdGFyZ2V0dGluZyB0aGVtIGlzIHN0aWxsIHRvbyBlYXJseSB0byBzYXksIGhvd2V2ZXIsIGl0IHNlZW1zIHRoYXQgb24gYXZlcmFnZSBoaXNwYW5pYy9sYXRpbm8gYW5kIGJsYWNrIHBlb3BsZSBhcmUgbW9yZSBsaWtlbHkgdG8gYmUgYSB2aWN0aW0gaW4gdGhlc2UgbWFzcyBtdXJkZXJzIGF0IHRoZSBhdmVyYWdlIGFnZSBvZiB+MjUuIEFtZXJpY2FuIEluZGlhbiBpcyBhcm91bmQgfjMwIGFuZCBBc2lhbi9QYWNpZmljIElzbGFuZGVyIHdpdGggV2hpdGUgYXZlcmFnZSBhdCBhcm91bmQgfjM1Lg0KDQpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSAxMH0NCiMgQ29tbWVudGVkIG91dCBKaXR0ZXIgYXMgdG9vIG1hbnkgb2JzZXJ2YXRpb25zIGNhdXNlcyB2aXN1YWwgY2x1dHRlci4NCg0KZ2dwbG90KHZpY3RpbXNDbGVhbiwgYWVzKHggPSByYWNlLCB5ID0gYWdlLCBmaWxsID0gcmFjZSkpICsNCiAgI2dlb21faml0dGVyKHNoYXBlID0gMTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjIpLCBhbHBoYSA9IDAuNikgKyANCiAgZ2VvbV92aW9saW4odHJpbSA9IFRSVUUsIGFscGhhID0gMC45LCBzY2FsZSA9ICJ3aWR0aCIpICsNCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4xKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpICsNCiAgbGFicyh0aXRsZSA9ICJTaG93Y2FzZSBEZW5zaXR5IG9mIFZpY3RpbXMnIFJhY2UgdG8gQWdlIiwgeCA9ICJSYWNlIiwgeSA9ICJBZ2UiKQ0KYGBgDQoNCmBgYHtyfQ0KdmljdGltQ291bnRSYWNlDQpgYGANCg0KSSByZWNhbGxlZCBpbiB0aGUgcGFzdCB0aGF0IHRoZXJlIHdhcyBhIGRpc2NyaW1pbmF0b3J5IGF0dGFjayBhdCB0aGUgZ2F5IE9ybGFuZG8gbmlnaHQgY3ViIG5hbWVkIFB1bHNlLiBUaGlzIG1hZGUgbWUgd29uZGVyIGlmIHRoZXJlIHdlcmUgYW55IG90aGVyIGRpc2NyaW1pbmF0b3J5IGF0dGFja3MsIHdoaWxlIHRoYXQgaW5jaWRlbnQgd2FzIGNoYWxrZWQgdXAgdG8gdGVycm9yaXNtLCBpdCBzdGlsbCB3YXMgYW4gYXR0YWNrIG9uIGEgbG9jYXRpb24gd2hlcmUgdGhlIHRhcmdldCBhdWRpZW5jZSB3YXMgcHJlZG9taW5hbnRseSBnYXkgbWVuLiANCkhlcmUgSSB3YXMgY2hlY2tpbmcgaWYgdGhlcmUgYXJlIGFueSBvdGhlciBkaXNjcmltaW5hdG9yeSBhdHRhY2tzIGFnYWluc3QgZ2F5IHBlb3BsZSBzZWFyY2hpbmcgdGhyb3VnaCB0aGUgbmFycmF0aXZlcyBmb3IgdGhlIHRlcm0gImdheSIsIHN1cnByaXNpbmdseSwgb3V0IG9mIGFsbCB0aGUgb25lcyBpbiB0aGUgVVMgb25seSBvbmUgc2hvd2VkIHVwLCB3aGljaCBpcyB0aGUgc2FtZSBvbmUgZnJvbSBhYm92ZSB0aGF0IG9jY3VycmVkIGluIE9ybGFuZG8uDQoNClN1cnByaXNpbmdseSBlbm91Z2gsIG91dCBvZiB0aGUgNjAwKyBpbmNpZGVudHMgdGhlcmUgd2VyZSBiYXJlbHkgYW55IHRoYXQgc3BlY2lmaWNhbGx5IHdlcmUgdGFyZ2V0aW5nIHBlb3BsZSB3aGV0aGVyIGl0IGJlIGZvciB0aGVpciBzZXh1YWwgb3JpZW50YXRpb24gb3IganVzdCByYWNpc20uIE9mIGNvdXJzZSwgdGhpcyB3YXMgbG9va2luZyB0aHJvdWdoIHRoZSBuYXJyYXRpdmUgdG8gc2VlIGlmIHRoZXJlIHdlcmUgYW55IHRoYXQgbWF5IG5vdCBoYXZlIGJlZW4gaW5jbHVkZWQgaW4gdGhlIHNpdHVhdGlvbl90eXBlIG9mICJIYXRlIiBhbmQgdGhlIG9ubHkgb25lIG5vdCB0aGVyZSB3YXMgdGhlIE9ybGFuZG8gTmlnaHRjbHViIHNob290aW5nIGFuZCB0aGlzIGlzIGR1ZSB0byBsYXRlciBmdXJ0aGVyIGV2aWRlbmNlIG9mIGl0IGJlaW5nIGNhdGVnb3JpemVkIGFzIGEgdGVycm9yaXN0IGF0dGFjayBhcyB0aGUgb2ZmZW5kZXIgaGFkIGFmZmlsaWF0aW9ucyB0byBJU0lTLg0KDQpgYGB7cn0NCiMgV2l0aCBncmVwbCBJIGNhbiBzZWFyY2ggZm9yIHNwZWNpZmljIHdvcmRzIGluIHRoZSBuYXJyYXRpdmUgb3IgYW55IG90aGVyIG9mIHRoZSBzdHJpbmdzIG9mIHRleHRzIHRoYXQgZ2l2ZSBuYXJyYXRpdmVzLg0KaW5jaWRlbnRzICU+JQ0KICBmaWx0ZXIoZ3JlcGwoImdheSIsIG5hcnJhdGl2ZSkpDQoNCmluY2lkZW50cyAlPiUNCiAgZmlsdGVyKGdyZXBsKCJsZXNiaWFuIiwgbmFycmF0aXZlKSkNCg0KaW5jaWRlbnRzICU+JQ0KICBmaWx0ZXIoZ3JlcGwoInF1ZWVyIiwgbmFycmF0aXZlKSkNCg0KaW5jaWRlbnRzICU+JQ0KICBmaWx0ZXIoZ3JlcGwoIiBhbnRpIiwgbmFycmF0aXZlKSkNCg0KaW5jaWRlbnRzICU+JQ0KICBmaWx0ZXIoZ3JlcGwoIkxHQlQiLCBuYXJyYXRpdmUpKQ0KDQppbmNpZGVudHMgJT4lDQogIGZpbHRlcihzaXR1YXRpb25fdHlwZSA9PSAiSGF0ZSIpDQoNCmBgYA0KDQo=